#ifndef TEXTEDITOR_H
#define TEXTEDITOR_H

#include "editor.h"
#include "Indenter/indenter.h"

#include <QTextBlock>

QT_BEGIN_NAMESPACE
	class QPaintEvent;
	class QResizeEvent;
	class QSize;
	class QWidget;
	class QAbstractItemModel;
QT_END_NAMESPACE

class LineNumberArea;
class AutoCompletion;

class TextEditor : public Editor
{
	Q_OBJECT

	public:
		enum ProgrammingLanguage { NONE, C_CPLUSPLUS, PYTHON, SH_BASH, JAVA,
					   HTML, JAVASCRIPT, CSHARP, FORTRAN };

		TextEditor(DocumentManager *newManager);

		void paintLineNumbers(QPaintEvent *event);
		void setCompleter(AutoCompletion *newCompleter) { completer = newCompleter; }
		AutoCompletion *getCompleter() const { return completer; }
		void processKeyEvent(QKeyEvent *event) { Editor::keyPressEvent(event); }
		QString getWordToComplete() const;
		virtual Type getType() const { return TEXT; }

		virtual void saveFile();
		virtual void saveFile(QString);        //Save out actual file information
		virtual void saveFile(QByteArray&);
		virtual QString saveSession(QString);     //Initiate the saving process and grab other variables.
		virtual void loadFile(QString);
		virtual void loadFile(QByteArray);
		virtual void loadSession(QString filename, QStringList metadata);
		virtual void setMeta(QStringList);
		virtual QString getMeta();

		void setLongLineMarker(const int charPos);
		void canInsertFromMimeData(const QMimeData *source);
		void setProgrammingLanguage(const ProgrammingLanguage newLang);
		ProgrammingLanguage getProgrammingLanguage() const { return programmingLanguage; }

		void receiveChange(QByteArray change);

	public slots:
		virtual void textChanged(int position, int charsRemoved, int charsAdded);
		void setLineNumbers(const bool show);
		void changeProgrammingLanguage(QAction *langAction);

	protected:
		void paintEvent(QPaintEvent *event);
		void resizeEvent(QResizeEvent *event);
		void moveEvent(QMoveEvent *event);
		void keyPressEvent(QKeyEvent *event);
		void mousePressEvent(QMouseEvent *event);

		void insertFromMimeData(const QMimeData *source);
		void matchOpeningChar(QKeyEvent *event);

	signals:
		void pressedNewLine();

	private slots:
		int updateLineNumberAreaWidth();
		void windowMoved();
		void preferencesChanged();

	private:
		int longLinePos;
		LineNumberArea *lineNumberArea;
		AutoCompletion *completer;
		Indenter *indenter;
		bool showLineNumbers;
		ProgrammingLanguage programmingLanguage;
		bool charMatchingEnabled;	//if bracket matching is turned on

		QChar getOppositeChar(const QChar ch) const;
		bool hasOppositeChar(const QChar ch) const;
};

/**
  * This class is full of ghey, but it makes more sense to keep it.
  */
class LineNumberArea : public QWidget
{
	public:
		LineNumberArea(TextEditor *newEditor) : QWidget(newEditor) { editor = newEditor; }

	protected:
		void paintEvent(QPaintEvent *event) { editor->paintLineNumbers(event); }

	private:
		TextEditor *editor;
};

#endif // TEXTEDITOR_H

